#include "sys_config.h"
#include "api/libc/printf.h"
#include "api/libc/string.h"
#include "api/libc/alloc.h"
#include "osal/osal.h"

#include <api/libosd/osd_lib.h>
#include <api/libosd/osd_common_draw.h>

#include "osd_config.h"
#include "osd_rsc.h"

#include "images.id"

#define MULTI_MENU_LANG 1

//#define SCALE_FONT_SUPPORT	// only use first set font.

#ifdef OSD_16BIT_SUPPORT
    #ifndef SD_UI
    #include "rsc/bmp_16/bitmaps_array.h"
    #include "rsc/font/fonts_array_1bit.h"
    
    #ifdef FONT_1BIT_SUPPORT
    #define font_asc 	font_asc_1bit
    #define font_lat1	font_lat1_1bit
    #define font_late 	font_late_1bit
    #define font_grk	font_grk_1bit
    #define font_cry	font_cry_1bit
    #define font_arb	font_arb_1bit
    #define font_thai   font_thai_1bit
    #else
    #include "rsc/font_4bit/fonts_array.h"
    #endif
    #else
	#include "rsc/bmp_sd_16/bitmaps_array.h"
	#include "rsc/font_sd/fonts_array.h"
	#include "rsc/font_sd/fonts_array_1bit.h"
    #endif
#else
#ifdef SD_UI
#include "rsc/bmp_sd_8/bitmaps_array.h"
#include "rsc/font_sd/fonts_array.h"
#include "rsc/font_sd/fonts_array_1bit.h"
//#include "rsc/font/fonts_array_1bit.h"

//#define font_asc 	font_asc_1bit
//#define font_lat1	font_lat1_1bit
//#define font_late 	font_late_1bit
//#define font_grk	font_grk_1bit
//#define font_cry	font_cry_1bit
//#define font_arb	font_arb_1bit

#else
#include "rsc/bmp/bitmaps_array.h"
#include "rsc/font/fonts_array_1bit.h"

#define font_asc 	font_asc_1bit
#define font_lat1	font_lat1_1bit
#define font_late 	font_late_1bit
#define font_grk	font_grk_1bit
#define font_cry	font_cry_1bit
#define font_arb	font_arb_1bit
#define font_thai	font_thai_1bit
#endif

#endif

#include "rsc/str/strings_array.h"
#include "rsc/pal/palettes_array.h"
#include "rsc/wstyle/winstyles_array.h"

#include <api/libchar/lib_char.h>
#define RSC_PRINTF(...)

#define FONT_BMP_LEN  1024*250    // modified by arvinzeng 100k to 250k

#define SUPPORT_MULTI_TASK 

static ID_RSC	gLangEnv = 0;
static UINT8	cur_wstyle = 0;
static const char* cur_string;
#ifdef SUPPORT_MULTI_TASK
static UINT8 *font_bitmap[SYS_OS_TASK_NUM] = {NULL};
#else
static UINT8 font_bitmap[FONT_BMP_LEN];
#endif
struct font_size_scale
{
	UINT32 w_mul;
	UINT32 w_div;
	UINT32 h_mul;
	UINT32 h_div;
};

struct font_size_scale font_size_ary[FONT_MAX_SIZE] =
{
	{1,1,  1,1},
	{1,1,  1,1},
	{3,2,  3,2},
	{1,1,  1,1},
};

#ifdef BIDIRECTIONAL_OSD_STYLE
static BOOL mirror_flag;
#endif

/*******************************************************************/
/*		Local function defintion
/*******************************************************************/
static UINT8 get_font_size_index(UINT16 wLibClass)
{
	unsigned char fontsize;

	fontsize = wLibClass&0xFF;  
	if(fontsize > FONT_MAX_SIZE )
		fontsize = FONT_MAX_SIZE-1;
	return fontsize;
}

#ifdef SCALE_FONT_SUPPORT
static void OSD_SetOnePix(UINT8 *buf, UINT32 pos, UINT8 n, UINT32 data)
{
	UINT8 clu;
	UINT32 byte_pos;

    static UINT8 mask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

	if(n == 4)
	{
		clu = *(buf + (pos >> 1));
		if ((pos & 1) == 0)
			clu = (clu&0x0f)|((data&0x0f)<<4);
		else
			clu = (clu&0xf0)|((data&0x0f));

		*(buf + (pos >> 1)) = clu;
	}
	else if(n == 1)
	{
		byte_pos = pos >> 3;
		clu = buf[byte_pos];
		clu |= mask[pos & 7];
		buf[byte_pos] = clu;
	}
}

static UINT32 OSD_GetOnePix(const UINT8 *buf, UINT32 pos, UINT8 n)
{
	UINT8 clu;
    static UINT8 mask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

	if (n == 4)
	{
		clu = *(buf + (pos >> 1));
		if ((pos & 1) == 0)
			clu >>= 4;
		return clu & 0x0f;
	}
	else if (n == 1)
	{
		clu = *(buf + (pos >> 3));
		return (clu & mask[pos & 7]);		
	}
	else if (n == 8)
	{
		return buf[pos];
	}
	else if (n == 16)
	{
		return *(UINT16* )(buf+(pos<<1));
	}
	else if(n == 32)
	{
		return *(UINT32* )(buf+(pos<<2));
	}	
}

static UINT32 xy2pos(UINT32 x, UINT32 y, UINT32 width, UINT32 bpp)
{
	UINT32 pos, dw_per_line, byte_per_line,pos_per_line;
	UINT32 stride;

	
	if(bpp == 1)
	{
		stride = (width+7)/8;
		pos_per_line = stride*8;
	}
	else if(bpp == 4)
	{
		#if 1
		dw_per_line = (width*bpp+31)/32;
		byte_per_line = dw_per_line*4;
		pos_per_line = byte_per_line*2;
		#else
		stride = (width*4+7)/8;
		pos_per_line = stride*2;		
		#endif
		
	}
	
	pos = x*pos_per_line + y;
	return pos;
}

static BOOL OSD_ScaleCharMatrix(UINT16 wLibClass, UINT32 width, UINT32 height, const font_t *font, OBJECTINFO* pObjectInfo, UINT8 *font_buffer, UINT8 *bmp_buffer, UINT8 bpp)
{
    UINT32 i, j, pos, one_bit, x0,y0,out_pos;
	UINT32 out_width, out_height;
	UINT32 cur_width, cur_height, inc_w, inc_h;
	UINT32 fontsize = get_font_size_index(wLibClass);

	if( font_size_ary[fontsize].w_mul == font_size_ary[fontsize].w_div && 
		font_size_ary[fontsize].h_mul == font_size_ary[fontsize].h_div )
		return FALSE;

	out_width = width * font_size_ary[fontsize].w_mul/font_size_ary[fontsize].w_div;
	out_height = height * font_size_ary[fontsize].h_mul/font_size_ary[fontsize].h_div;

	
	inc_w = (width<<16) / out_width;
	inc_h = (height<<16) / out_height;

	UINT32 buffer_len = (out_width * out_height) + 7;
	if(buffer_len>FONT_BMP_LEN/2)
	{
		ASSERT(0);
	}
	MEMSET(bmp_buffer, 0, buffer_len);
	cur_height = 0;
    for(i = 0; i < out_height; i++)
    {
		cur_width = 0;
		for (j = 0; j < out_width; j++)
		{
			x0 = (cur_height>>16);
			y0 = (cur_width>>16);
			pos = xy2pos(x0, y0, width, bpp);
			out_pos = xy2pos(i, j, out_width, bpp);
	        UINT32 one_bit = OSD_GetOnePix(font_buffer, pos, bpp);
			if (one_bit)
			{
				OSD_SetOnePix(bmp_buffer, out_pos, bpp, one_bit);
			}
			cur_width += inc_w;
			//libc_printf("i=%d:j=%d:pos=%d,out_pos=%d,one_bit=%d\n", i, j, pos,out_pos,one_bit);
		}
		cur_height += inc_h;
    }	
	pObjectInfo->m_objAttr.m_wHeight = out_height;
	pObjectInfo->m_objAttr.m_wWidth= out_width;	
	pObjectInfo->m_objAttr.m_wActualWidth *= font_size_ary[fontsize].w_mul/font_size_ary[fontsize].w_div;
	return TRUE;
}
#endif

// Font search
static BOOL OSDSearch(UINT16 uStart ,UINT16 uEnd, UINT16 uAim, UINT16* pTab, UINT16* uIdx )
{
	UINT16		start, end, len;
	UINT16		midValue;
	
	for(start = uStart, end =uEnd; start <= end;)
	{
		midValue = pTab[(start + end + 1)/2];

		if((start == end) && ( uAim != midValue))
			return FALSE;

		if(uAim > midValue)
		{
			start = (end + start+1)/2;
		}
		else if(uAim < midValue)
		{
			end = (end + start)/2;			
		}
		else
		{
			*uIdx = (start + end + 1)/2;
			return TRUE;
		}

	}
	return FALSE;
}



static BOOL OSDSearchFont(font_t* font, UINT16* pIdx)
{
	UINT16		uIdx = *pIdx;

	if(uIdx <  font->uIdxTab[0])
		return FALSE;
	
	return OSDSearch(0, (font->uFontCnt  - 1), uIdx, (UINT16*)font->uIdxTab, pIdx);
}

static const font_t* get_font3(UINT16 wLibClass,UINT16* wIndex)
{
	unsigned char fontsize;
	font_t* font;
	unsigned char* ch,high;
    UINT16 lib_type,font_idx;
  
	fontsize = wLibClass & 0x00FF;    
    lib_type = wLibClass & 0xFF00;
    
//	if(fontsize!=0)		PRINTF("!!!!!!!!!!!!!fontsize=%d\n",fontsize);
	if(fontsize > FONT_MAX_SIZE )
		fontsize = FONT_MAX_SIZE-1;

#ifdef SCALE_FONT_SUPPORT
	fontsize = 0;
#endif

	switch(lib_type)
	{
		case LIB_FONT_DEFAULT:
			font = &font_asc_1bit[fontsize];
			break;
			
#if(AOV_THAI_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_THAI:
			font = &font_thai_1bit[fontsize];
			break;
#endif                        
            
#if(AOV_VIE_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_VIE:
			font = &font_vie_1bit[fontsize];
			break;
#endif                        
            
#if(AOV_CHS_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_CHS:
			font = &font_chs_1bit[fontsize];
			break;
#endif                        
            
#if(AOV_ARABIC_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_FONT_ARABIC:
			font = &font_arb_1bit[fontsize];
			break;
#endif     

#if(AOV_TAMIL_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_TAM:
			font = &font_tam_1bit[fontsize];
			break;
#endif
#if(AOV_RUS_SUPPORT_ENABLE == SYS_FUNC_ON)||(AOV_UKRA_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_CYRILLIC:
			font = &font_cry_1bit[fontsize];
			break;
#endif



        default:
                return NULL;
    }
            
    if(font->uIdxTab == NULL)
    {
        if(*wIndex > font->uFontCnt )   
            return NULL;
    }
    else
    {
        font_idx = *wIndex;
    
        switch(lib_type)
        {
            case LIB_FONT_DEFAULT:
            case LIB_FONT_LATIN1:   
            case LIB_FONT_LATINE:
            case LIB_FONT_ARABIC:
                break;
            default:
                ;
        }
        
        if(OSDSearchFont(font,wIndex) == FALSE)
             return NULL;
    }

	return font;

}

static const font_t* get_font_1bit(UINT16 wLibClass,UINT16* wIndex)
{
    UINT16 wc = *wIndex;
    const font_t *pfont = get_font3(wLibClass, &wc);

    if (pfont == NULL)
    {
        wc = '-';
        pfont = get_font3(wLibClass, &wc);
    }
    *wIndex = wc;

    return pfont;
}


static const font_t* get_font2(UINT16 wLibClass,UINT16* wIndex)
{
	unsigned char fontsize;
	font_t* font;
	unsigned char* ch,high;
    UINT16 lib_type,font_idx;
  
	fontsize = wLibClass & 0x00FF;    
    lib_type = wLibClass & 0xFF00;
    
//	if(fontsize!=0)		PRINTF("!!!!!!!!!!!!!fontsize=%d\n",fontsize);
	if(fontsize > FONT_MAX_SIZE )
		fontsize = FONT_MAX_SIZE-1;

#ifdef SCALE_FONT_SUPPORT
	fontsize = 0;
#endif

	switch(lib_type)
	{
		case LIB_FONT_DEFAULT:
			font = &font_asc[fontsize];
			break;

#if(AOV_THAI_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_FONT_THAI:
			font = &font_thai_1bit[fontsize];
			break;
#endif

#if(AOV_VIE_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_VIE:
			font = &font_vie_1bit[fontsize];
			break;
#endif     

#if(AOV_CHS_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_CHS:
			font = &font_chs_1bit[fontsize];
		break;
#endif

#if(AOV_ARABIC_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_ARABIC:
			font = &font_arb_1bit[fontsize];
		break;		
#endif
		
#if(AOV_TAMIL_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_TAM:
			font = &font_tam_1bit[fontsize];
		break;	
#endif

#if(AOV_RUS_SUPPORT_ENABLE == SYS_FUNC_ON)||(AOV_UKRA_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_FONT_CYRILLIC:
			font = &font_cry_1bit[fontsize];
		break;
#endif



        default:
                return NULL;
    }
            
    if(font->uIdxTab == NULL)
    {
        if(*wIndex > font->uFontCnt )   
            return NULL;
    }
    else
    {
        font_idx = *wIndex;
    
        switch(lib_type)
        {
            case LIB_FONT_DEFAULT:
            case LIB_FONT_LATIN1:   
            case LIB_FONT_LATINE:
            case LIB_FONT_ARABIC:
                break;
            default:
                ;
        }
        
        if(OSDSearchFont(font,wIndex) == FALSE)
             return NULL;
    }

	return font;

}

static const font_t* get_font(UINT16 wLibClass,UINT16* wIndex)
{
    UINT16 wc = *wIndex;
    const font_t *pfont = get_font2(wLibClass, &wc);

    if (pfont == NULL)
    {
        wc = '-';
        pfont = get_font2(wLibClass, &wc);
    }
    *wIndex = wc;

    return pfont;
}

// BMP decoder
static unsigned long bmp_rle_decode(const unsigned char* rle_bmp_data,unsigned long data_size, unsigned char* bmp_data)
{
	unsigned long i,out_size;
	unsigned char k,size;

	out_size = 0;
	i = 0;
	do
	{
		size = *(rle_bmp_data + i);
		if(size<128)
		{
			for(k=0;k<size;k++)
				*(bmp_data + out_size + k) = *(rle_bmp_data + i + 1);
			i+= 2;
		}
		else
		{
			size -= 128;
			for(k=0;k<size;k++)
				*(bmp_data + out_size + k) = *(rle_bmp_data + i + 1 + k);
			i+= size + 1;
		}

		out_size += size;
	}while(i!=data_size);

	return out_size;
}

static UINT32 bmp_rle16_decode(unsigned char* rle16_bmp_data,unsigned long data_size, unsigned char* bmp_data)
{
	unsigned long i,out_size;
	unsigned char k,size;

	out_size = 0;
	i = 0;
	do
	{
		size = *(rle16_bmp_data + i);
		if(size<128)
		{
			for(k=0;k<size;k++)
			{
				*(bmp_data + out_size + k*2) = *(rle16_bmp_data + i + 1);
				*(bmp_data + out_size + k*2 + 1) = *(rle16_bmp_data + i + 2);
			}
			i+= 3;
		}
		else
		{
			size -= 128;
			for(k=0;k<size;k++)
			{
				*(bmp_data + out_size + k*2) = *(rle16_bmp_data + i + 1 + k*2);
				*(bmp_data + out_size + k*2 + 1) = *(rle16_bmp_data + i + 2 + k*2);
			}
			i+= size*2 + 1;
		}

		out_size += size*2;
	}while(i!=data_size);

	return out_size;
}

static long bmp_rle32_decode(BYTE *inBuf,unsigned long buflen,BYTE  *outBuf,BYTE ByteOfPixel)
{
	unsigned char *pBuf,*pOutBuf;
	long nDataLen,nLen;
	long nPixelDataLen;
	long ret = 0;
	int  i; 
	pBuf = inBuf;
	pOutBuf = outBuf;
    nDataLen = (long)buflen;
	if(ByteOfPixel < 3)
	{
		return (-1);
	}
	while(nDataLen > 0)
	{
		if(*pBuf & 0x80) //
		{   
			//nPixelDataLen = (long)(*pBuf & ~0x80) * ByteOfPixel;
			nPixelDataLen = (long)(*pBuf & ~0x80) << 2;
			pBuf++;
			for(i = 0;i < nPixelDataLen; i++)
			{
				*pOutBuf++ = *pBuf++; 
			}
			nDataLen -= nPixelDataLen + 1;

			
		}
		else
		{
			//nPixelDataLen = (long)(*pBuf & ~0x80) * ByteOfPixel;
            nPixelDataLen = (long)(*pBuf & ~0x80) << 2;
            pBuf++;
			for(i = 0;i < nPixelDataLen; i++)
			{
				//*pOutBuf++ = *(pBuf + i%ByteOfPixel); 
				*pOutBuf++ = *(pBuf + (i & 0x03)); 
			}
            pBuf += ByteOfPixel;  
			nDataLen -= ByteOfPixel + 1;
            
		}
		ret += nPixelDataLen;
	}
	return ret;
}
// 
static ID_RSC OSDExt_GetFontLibId(UINT16 EnvID)
{
	lpLANG_TABLE	pLangTab =(lpLANG_TABLE) g_LangRscMapTable;
	UINT8			i;

	for (i=0; i<SIZE_LANG_TABLE; i++)
		if (pLangTab->LangId == EnvID)
			return pLangTab->FontId;
		else
			pLangTab++;

	return LIB_FONT_DEFAULT;
}
/*******************************************************************/
/*		Local function defintion
/*******************************************************************/

UINT16 OSD_GetLangEnvironment(void)
{
//	return g_FontCache[LIB_CACHE_COUNT-1].m_wFontClass;
	return gLangEnv;
}

BOOL OSD_SetLangEnvironment(UINT16 langclass)
{
	ID_RSC			FontRscId;

	if(langclass >= SIZE_LANG_TABLE)
		langclass = 0;

	gLangEnv = langclass;
	FontRscId = OSDExt_GetMsgLibId(langclass);
	
	switch(FontRscId)
	{

#if(AOV_THAI_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_THAI:
            cur_string = Thai_strs_array;
            PRINTF("========Change to LIB_STRING_THAI=========\n");
			break;
#endif
#if(AOV_VIE_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_VIE:
            cur_string = Vietnam_strs_array;
            PRINTF("========Change to LIB_STRING_VIE=========\n");
            break;
#endif            
#if(AOV_CHS_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_CHS:
            cur_string = Chinese_S_strs_array;
            PRINTF("========Change to LIB_STRING_CHS=========\n");
            break;    
#endif
#if(AOV_MALAY_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_MALAY:
            cur_string = Malaysia_strs_array;
            PRINTF("========Change to LIB_STRING_MALAY=========\n");
            break;    
#endif
#if(AOV_IND_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_IND:
            cur_string = Indonesia_strs_array;
            PRINTF("========Change to LIB_STRING_IND=========\n");
            break;
#endif
#if(AOV_ARABIC_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_ARABIC:
            cur_string = Arabic_strs_array;
            PRINTF("========Change to LIB_STRING_ARABIC=========\n");
            break;
#endif

#if(AOV_TAMIL_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_TAMIL:
            cur_string = Tamil_strs_array;
            PRINTF("========Change to LIB_STRING_TAMIL=========\n");
		break;
#endif            

#if(AOV_RUS_SUPPORT_ENABLE == SYS_FUNC_ON)
        case LIB_STRING_RUS:
            cur_string = Russia_strs_array;
            PRINTF("========Change to LIB_STRING_TAMIL=========\n");
		break;
#endif

#if(AOV_UKRA_SUPPORT_ENABLE == SYS_FUNC_ON)
			case LIB_STRING_UKR://Ukrainian
					cur_string = Ukrainian_strs_array;
					break;
#endif
		case LIB_STRING_ENGLISH:          
			cur_string = English_strs_array;	
			break;	

		default:		            
			cur_string = English_strs_array;		
			PRINTF("========Change to LIB_STRING_ENGLISH=========\n");
			break;
	}
#ifdef BIDIRECTIONAL_OSD_STYLE
	switch(FontRscId)
	{
#if(MULTI_MENU_LANG	)
#if(AOV_ARABIC_SUPPORT_ENABLE == SYS_FUNC_ON)
		case LIB_STRING_ARABIC:
#endif
#ifdef PERSIAN_SUPPORT
		case LIB_STRING_PERSIAN:
#endif
			mirror_flag = TRUE;
			break;
#endif
		default:
			mirror_flag = FALSE;
			break;
	}
#endif
}

#ifdef BIDIRECTIONAL_OSD_STYLE
static void check_mirror_flag(UINT16 wLibClass, UINT16 uIndex, OBJECTINFO* pObjectInfo)
{
	UINT16	wClass;
	wClass=wLibClass&0xF000;

	// check for security
	// if the lib is one of the following two,pObjectInfo maynot be a empty value
	if(((wClass==LIB_FONT)||(wClass==LIB_ICON))&&(pObjectInfo==NULL))
		return;
    
	if(wClass==LIB_ICON)
	{
		if (OSD_GetMirrorFlag() == TRUE)
		{
			UINT16 tmpIndex = uIndex;
			if (tmpIndex == IM_CHANNELLIST_TV || tmpIndex == IM_CHANNELLIST_RADIO
				|| tmpIndex == IM_CHANNELLIST_MEDIAPLAY|| tmpIndex == IM_CHANNELLIST_PVR
				|| tmpIndex == IM_ORANGE_ARROW_S
				|| tmpIndex == IM_EPG || tmpIndex == IM_INFORMATION_PVR
				|| tmpIndex == IM_VOLUME
				|| tmpIndex == IM_INFORMATION_TV || tmpIndex == IM_INFORMATION_RADIO
				|| tmpIndex == IM_SATELLITE || tmpIndex == IM_RECEIVE
				|| tmpIndex == IM_SATELLITE_LINE_1 || tmpIndex == IM_SATELLITE_LINE_2 || tmpIndex == IM_SATELLITE_LINE_3
				|| tmpIndex == IM_SATELLITE_LINE_4 || tmpIndex == IM_SATELLITE_LINE_5
// Gavim@ARABIC
//				|| tmpIndex == IM_MEDIAPLAYER || tmpIndex == IM_MEDIAPLAYER_ON || tmpIndex == IM_MEDIAPLAYER_SELECT
				|| tmpIndex == IM_CHANNEL || tmpIndex == IM_CHANNEL_ON || tmpIndex == IM_CHANNEL_SELECT
				|| tmpIndex == IM_INSTALLATION || tmpIndex == IM_INSTALLATION_ON || tmpIndex == IM_INSTALLATION_SELECT
				|| tmpIndex == IM_SYSTEM || tmpIndex == IM_SYSTEM_ON || tmpIndex == IM_SYSTEM_SELECT
				|| tmpIndex == IM_TOOLS || tmpIndex == IM_TOOLS_ON || tmpIndex== IM_TOOLS_SELECT
#if 1	/*Maker_GUI_ON*/
// Gavim@ARABIC
//				|| tmpIndex == IM_GAME_SELECT
#endif

#ifdef RECORD_SUPPORT
				|| tmpIndex == IM_PVR || tmpIndex == IM_PVR_ON || tmpIndex == IM_PVR_SELECT
#endif
			)
				pObjectInfo->m_objAttr.m_mirrorFlag = FALSE;
			else
				pObjectInfo->m_objAttr.m_mirrorFlag = TRUE;
		}
		else
			pObjectInfo->m_objAttr.m_mirrorFlag = FALSE;
	}
}
#endif

UINT8 font_bitmap_thai[1024*12];
UINT32 thai_font_buf[1024*12];
UINT32 font_temp[50];
extern UINT8 thai_get_chlevel(unsigned short code);

struct font_real_region OSD_ThaiGetRealRegion(UINT32 *source,/* UINT32 data_size, */UINT8 font_height, UINT8 font_width)
{
    UINT32 cur_pix = 0;
    UINT32 u32_offset = 0;
    UINT32 u32 = 0;
    UINT8 column_count = 0;
    UINT8 row_count = 0;
    UINT8 column_temp = 0;
    UINT8 row_temp = 0;
    UINT8 i = 0;
    UINT8 j = 0;

    struct font_real_region font_region;
    MEMSET(&font_region, 0x0 ,sizeof(struct font_real_region));
    font_region.left_most = font_width;
    font_region.right_most = 0;
    for(i = 0; i < font_height; i++)
    {
        for(j = 0; j < font_width; j++,cur_pix++)
        {
            u32_offset = cur_pix & 0x1F;
            if(u32_offset == 0)
            {
                u32 = *(source + (cur_pix>>5));
            }

            if(u32 & (0x80000000>>u32_offset))
            {           
                if(row_temp != i)
                {
                    row_temp = i;
                    row_count ++;
                    if(row_count == 1)
                    {
                        font_region.top_most = i;
                    }
                }
                
                column_temp = j;
                column_count++;
                if(column_count == 1)
                {
                    if(font_region.left_most > j)
                    {
                        font_region.left_most = j;
                    }
                }
                //libc_printf("line: %d \t row: %d \n", j, i);
            }
        }
        if(font_region.right_most < column_count)
        {
            font_region.right_most = column_temp;
        }
        column_count = 0;

    }
    font_region.bottom_most = row_temp;

    return font_region;
}

UINT8* 	OSD_GetThaiFontData(UINT16 wLibClass,struct thai_cell *cell,OBJECTINFO* pObjectInfo)
{
	const font_t*	font[3];
	UINT16 wIndex[3],stride;
	UINT8* pbDatabuf,*font_byte=NULL;
	UINT32 i,j,k,font_width,font_height,font_max_width;
	UINT32 *pu32;
	UINT32 size,data_offset,u32 = 0,u32_offset,bit_offset,cur_pix;
	UINT32 dest_pix, dest_offset,dest_byte_offset,dest_bit_offset;
	UINT32 *font_word = NULL, *font_buf;

	UINT8 thai_chlevel;
	BOOL bAbove = FALSE;
	UINT32 *thai_temp = font_temp;
    UINT8 align_right_flag = 1;     //default align right
    UINT8 align_bottom_flag = 1;    //default align bottom 
    UINT32 data_size = 0;
    UINT8 width = 0;
    UINT8 left_offset = 0;
    UINT8 font_height_cell = 0;
    struct font_real_region thai_real_region[3];
    struct shift_offset shift_offset_temp;

    MEMSET(&thai_real_region, 0x0, sizeof(struct font_real_region) * 3);
    MEMSET(&shift_offset_temp, 0x0, sizeof(struct shift_offset));

	RSC_PRINTF("Call %s:\n",__FUNCTION__);

	pObjectInfo->m_wObjClass=wLibClass;
	
	font_max_width = 0;
	font_height = 0;

	for(i=0; i<cell->char_num; i++)
	{
		wIndex[i] = cell->unicode[i];
		
		font[i] = get_font(wLibClass,&wIndex[i]);
		if(font[i]==NULL)	
			return NULL;

		if(font_max_width < font[i]->width[wIndex[i]])
		{
			font_max_width = font[i]->width[wIndex[i]];
			font_height =  font[i]->height;
		}

        if((0x0e33 == cell->unicode[i]))
        {
            align_right_flag = 0;
        }
	}

	pObjectInfo->m_objAttr.m_wWidth = (font_max_width+7)/8*8;
    font_height_cell = font_height + THAI_HEIGHT_COMPENSATE;
    pObjectInfo->m_objAttr.m_wHeight = font_height_cell;
	pObjectInfo->m_objAttr.m_wActualWidth = font_max_width;
	pObjectInfo->m_objAttr.m_bColor	= 1;
	stride = (font_max_width+7)/8;

	MEMSET(font_bitmap_thai,0,font_height_cell*stride);
	
	font_buf = thai_font_buf;//MALLOC(((font_height*font_max_width+31)/32)*4);
	MEMSET(font_buf, 0, ((font_height_cell*font_max_width+31)/32)*4);

	for(i=0; i<cell->char_num; i++)
	{
	    align_bottom_flag = 1;
		// get wIndex font offset
		data_offset = 0;
		for(j=0;j<wIndex[i];j++)
		{
			font_width = font[i]->width[j];
			size = (font_width * font_height + 31)>>5;//32;
			data_offset += size;
		}
		pu32 = (UINT32*)(font[i]->data + data_offset);

		thai_chlevel= thai_get_chlevel(cell->unicode[i]);
        width = font[i]->width[wIndex[i]];
	    data_size = ((font[i]->width[wIndex[i]])*(font[i]->height)+31)>>5;
	    MEMSET(thai_temp, 0, data_size*4);
        
		if(1 == i)
		{
		    if((2 == thai_chlevel) || (4 == thai_chlevel))
		    {
    		    if(2 == thai_chlevel)
    		    {
    			    bAbove = TRUE;
                }
                if((0x0E1B == cell->unicode[0]) || (0x0E1D == cell->unicode[0]) || (0x0E1F == cell->unicode[0]))   //special case: 0x0e1b, 0x0e1d,0x0e1f
                {
                    if(0x0e48 != cell->unicode[i])
                    {
                        thai_real_region[i] = OSD_ThaiGetRealRegion(pu32, font_height, width);
                        //left_offset = thai_real_region[i].left_most - 1;
                        //libc_printf("left:%d right:%d top:%d bottom:%d\n",thai_real_region[i].left_most,thai_real_region[i].right_most,thai_real_region[i].top_most,thai_real_region[i].bottom_most);
                        shift_offset_temp.left_offset = thai_real_region[i].left_most - 1;  // keep at least 1 bit
                    }
                    else
                    {
                        shift_offset_temp.left_offset = width/4;
                    }
                    align_right_flag = 0;
                }
                if(0x0E33 == cell->unicode[2])
                {
                    thai_real_region[i] = OSD_ThaiGetRealRegion(pu32, font_height, width);
                    shift_offset_temp.up_offset = thai_real_region[i].top_most;
                    align_bottom_flag = 0;
                }
            }
		}
        
		if( i == 2)
		{
		    if(4 == thai_chlevel)       //TOP
		    {
		        if(bAbove == TRUE)
	            {
	                shift_offset_temp.down_offset = 0;

        		    thai_real_region[i] = OSD_ThaiGetRealRegion(pu32, font_height, width);
                    shift_offset_temp.up_offset = thai_real_region[i].top_most;
                    align_bottom_flag = 0;
	            }
                else
                {
                    if((0x0E1B == cell->unicode[0]) || (0x0E1D == cell->unicode[0]) || (0x0E1F == cell->unicode[0]))	//special case: 0x0e1b, 0x0e1d,0x0e1f
                    {
                        if(0x0e48 != cell->unicode[i])
                        {
                            thai_real_region[i] = OSD_ThaiGetRealRegion(pu32, font_height, width);
                            //libc_printf("left:%d right:%d top:%d bottom:%d\n",thai_real_region[i].left_most,thai_real_region[i].right_most,thai_real_region[i].top_most,thai_real_region[i].bottom_most);
                            shift_offset_temp.left_offset = thai_real_region[i].left_most - 1;  // keep at least 1 bit
                        }
                        else
                        {
                            shift_offset_temp.left_offset = width/4;
                        }
                    }
                }
		    }
            else if((3 == thai_chlevel)||(1 == thai_chlevel))       //BELOW & BASE
            {
                shift_offset_temp.left_offset = 0;
                shift_offset_temp.right_offset = 0;
                shift_offset_temp.up_offset = 0;
                shift_offset_temp.down_offset = 0;
            }
		}

		font_width = font[i]->width[wIndex[i]];
		u32 = 0;
		cur_pix = 0;
        for(j = shift_offset_temp.up_offset; j < font_height - shift_offset_temp.down_offset; j++)
    	{
    		//dest_byte_offset = 0;
    		for(k = shift_offset_temp.left_offset ; k < font_width - shift_offset_temp.right_offset ; k++)
    		{
    		    cur_pix = font_width * j   + k;
    			u32_offset =   cur_pix & 0x1F;
                //libc_printf("cur_pix = %d \t u32_offset = %d \n",cur_pix, u32_offset);
    			if(u32_offset == 0 ||  k == shift_offset_temp.left_offset)
    		    {
        			u32	 = *(pu32 + (cur_pix>>5));
    		    }

                dest_pix = (THAI_HEIGHT_COMPENSATE * align_bottom_flag + j - shift_offset_temp.up_offset + shift_offset_temp.down_offset)*font_max_width + (font_max_width - (font_width - shift_offset_temp.right_offset))* align_right_flag  + k - shift_offset_temp.left_offset;

                dest_bit_offset = dest_pix & 0x1F;
    			if(dest_bit_offset == 0 || k == shift_offset_temp.left_offset)
    		    {
        			font_word = (UINT32*)&font_buf[dest_pix>>5];
    		    }
    			
    			if(u32 & (0x80000000>>u32_offset) )
    		    {
        			*font_word |= (0x80000000>> dest_bit_offset);
    		    }
    		}
    	}
	}
	
	pu32 = font_buf;
#ifdef GE_DRAW_OSD_LIB
	if(OSD_Get_Vscr_State())
        osal_cache_flush((UINT8 *)pu32,font_height_cell*font_max_width);
    return pu32;
#else
	font_width = font_max_width;
	cur_pix = 0;
	dest_offset = 0;
	u32 = 0;
	for(i=0;i<font_height_cell;i++,dest_offset+=stride)
	{
		dest_byte_offset = 0;
		for(j=0;j<font_width;j++,cur_pix++)
		{
			u32_offset =  cur_pix & 0x1F;
			if(u32_offset == 0)
				u32	 = *(pu32 + (cur_pix>>5));
			dest_bit_offset = j & 0x07;
			if(dest_bit_offset ==0)
				font_byte = &font_bitmap_thai[dest_offset + dest_byte_offset++];
			if(u32 & (0x80000000>>u32_offset) )
				*font_byte |= (0x80>> dest_bit_offset);
		}
	}

	//FREE(font_buf);
	
	pbDatabuf = font_bitmap_thai;
	RSC_PRINTF("Get LIB_ICON:  0x%04x,wIndex=%d OK!\n",wLibClass,wIndex);		

	return pbDatabuf;
#endif	

}

UINT8* 	OSD_GetRscObjData(UINT16 wLibClass,UINT16 uIndex/*UINT8* pbIndex*/,OBJECTINFO* pObjectInfo)
{
	UINT16 wIndex,wClass,stride;
	UINT16 wSite;
	
	const unsigned char* str_array;
	
	const font_t*	font;
	bitmap_infor_t* bmpinfo;
	
	BOOL fStatus;
	UINT8* pbDatabuf;


	unsigned long i,j,font_width,font_height;
	const unsigned long	*pu32;
	unsigned long offset,size,data_offset,u32 = 0,u32_offset,bit_offset,cur_pix,dest_offset,dest_byte_offset,dest_bit_offset;
	unsigned char *font_byte = NULL;
	unsigned long str_num;
    UINT32   tsk_id;     

	RSC_PRINTF("Call %s:\n",__FUNCTION__);

	pObjectInfo->m_wObjClass=wLibClass;
	
	wIndex=uIndex;//ComMB16ToWord(pbIndex);
	wClass = wLibClass&0xF000;
	
	if(wClass==LIB_ICON)
	{
		wIndex -= 0x8001;
		
		RSC_PRINTF("Get LIB_ICON: 0x%04x,wIndex=%d\n",wLibClass,wIndex);
		
		if(wIndex>=sizeof(bitmaps_infor)/sizeof(bitmaps_infor[0]))
			return NULL;

		bmpinfo = &bitmaps_infor[wIndex];
		
		pObjectInfo->m_objAttr.m_wWidth 	= bmpinfo->bmp_size/bmpinfo->h;
		pObjectInfo->m_objAttr.m_wHeight 	= bmpinfo->h;		
		pObjectInfo->m_objAttr.m_wActualWidth = bmpinfo->w;
		//pObjectInfo->m_objAttr.m_bColor	= 8;
	    //pObjectInfo->m_objAttr.m_bColor = (bmpinfo->bmp_size/(bmpinfo->h*bmpinfo->w))<<3;
        pObjectInfo->m_objAttr.m_bColor = bmpinfo->bit_count;
#ifdef BIDIRECTIONAL_OSD_STYLE
        check_mirror_flag(wLibClass,uIndex, pObjectInfo);
#endif

#ifdef SUPPORT_MULTI_TASK
        tsk_id = osal_task_get_current_id();
        if(font_bitmap[tsk_id - 1] == NULL)
        {
            font_bitmap[tsk_id - 1] = (UINT8 *)MALLOC(FONT_BMP_LEN);
        }
        if(bmpinfo->bmp_size > FONT_BMP_LEN)
            return NULL;
        else
            pbDatabuf = font_bitmap[tsk_id - 1];
#else
        if(bmpinfo->bmp_size > sizeof(font_bitmap) )
            return NULL;
        else
            pbDatabuf = font_bitmap;
#endif        
		if(pbDatabuf!=NULL)
		{
            if(32 == bmpinfo->bit_count ) //4 == (bmpinfo->bmp_size /(bmpinfo->h*bmpinfo->w)))
            {
				if((UINT32)bmp_rle32_decode((BYTE *)bmpinfo->data,bmpinfo->data_size,pbDatabuf,4)!=bmpinfo->bmp_size)
				{
					pbDatabuf = NULL;
				}
            }
			else if(16 == bmpinfo->bit_count )////2 == (bmpinfo->bmp_size /(bmpinfo->h*bmpinfo->w)))
			{
            #ifdef GE_DRAW_OSD_LIB
                VSCR src_vscr,dst_vscr;
                struct OSDRect  rect;
                dst_vscr.lpbScr     = pbDatabuf;
                
                src_vscr.lpbScr     = (UINT8 *)(bmpinfo->data);
                src_vscr.bColorMode = OSD_GetCurColorMode();//OSD_HD_ARGB1555;
                src_vscr.vR.uWidth  = bmpinfo->w;
                src_vscr.vR.uHeight = bmpinfo->h;
                src_vscr.vR.uTop    = 0;
                src_vscr.vR.uLeft   = 0;
                lib_ge_vscr_draw_color(&dst_vscr,&src_vscr,bmpinfo->bmp_size,bmpinfo->bit_count,&src_vscr.vR,NULL,0,5);
            #else
				if(bmp_rle16_decode((UINT8 *)bmpinfo->data,bmpinfo->data_size,pbDatabuf) !=bmpinfo->bmp_size)
				{
					ASSERT(0);
					pbDatabuf = NULL;
				}	
            #endif                
			}
            else
            {
                if(bmp_rle_decode(bmpinfo->data,bmpinfo->data_size,pbDatabuf)!=bmpinfo->bmp_size)
                {
                    //FREE(pbDatabuf);
                    pbDatabuf = NULL;
                }
            }
	            //else    printf("MALLOC 0X%08X(%dK)id=%d\t",pbDatabuf,bmpinfo->bmp_size/1024,wIndex);
        }
		
	//	pbDatabuf = bmpinfo->data;
		
	}
	else if(wClass==LIB_STRING)
	{
		wIndex -= 1;
		str_array = cur_string;
		RSC_PRINTF("0x%02x,0x%02x,0x%02x \n",str_array[0],str_array[1],str_array[2]);

		str_num = (str_array[1]<<8) + str_array[2];

		RSC_PRINTF("Get LIB_STRING: 0x%04x,wIndex=%d,str_num=%d\n",wLibClass,wIndex,str_num);
		if(wIndex>= str_num) return NULL;
		
		offset = (str_array[3 + 2*wIndex]<<8) + str_array[3 + 2*wIndex + 1];
		
		pbDatabuf = (UINT8*)&str_array[offset];	
		RSC_PRINTF("Get LIB_STRING: 0x%04x,wIndex=%d,offset=%d,pbDatabuf=0x%x\n",wLibClass,wIndex,offset,pbDatabuf);
		
	}
	else if(wClass==LIB_FONT)
	{
	
		RSC_PRINTF("Get LIB_ICON:  0x%04x,wIndex=%d\n",wLibClass,wIndex);

		font = get_font(wLibClass,&wIndex);
		if(font==NULL)	return NULL;
		
		pObjectInfo->m_objAttr.m_wWidth 	= (font->width[wIndex]+7)/8*8;
		font_height = pObjectInfo->m_objAttr.m_wHeight	= font->height;
		pObjectInfo->m_objAttr.m_wActualWidth = font->width[wIndex];
		pObjectInfo->m_objAttr.m_bColor	= 1;
		if(font->bit_cnt)
			pObjectInfo->m_objAttr.m_bColor	= font->bit_cnt;

		UINT8 bit_per_pix = pObjectInfo->m_objAttr.m_bColor;		
		pObjectInfo->m_objAttr.m_wWidth *= bit_per_pix;
    #ifdef SUPPORT_MULTI_TASK
        tsk_id = osal_task_get_current_id();
        if(font_bitmap[tsk_id - 1] == NULL)
        {
            font_bitmap[tsk_id - 1] = (UINT8 *)MALLOC(FONT_BMP_LEN);
        }
        if(OSD_Get_Vscr_State())
            MEMSET(font_bitmap[tsk_id - 1],0,font_height * pObjectInfo->m_objAttr.m_wWidth/(8/bit_per_pix));
    #else
		MEMSET(font_bitmap,0,font_height * pObjectInfo->m_objAttr.m_wWidth/(8/bit_per_pix));
    #endif
		data_offset = 0;
		for(i=0;i<wIndex;i++)
		{
			font_width = font->width[i];
			size = (font_width * font_height * bit_per_pix + 31)>>5;//32;
			data_offset += size;
		}
		
		pu32 = font->data + data_offset;
        if(OSD_Get_Vscr_State())
        {
    		font_width = font->width[wIndex];
    		stride = (font_width+7)/8*bit_per_pix;
    		cur_pix = 0;
    		dest_offset = 0;
    		RSC_PRINTF("%c,font_width=%d,font_height=%d,stride=%d,data_offset=%d\n",wIndex,font_width,font_height,stride,data_offset);
            u32 = 0;
    		for(i=0;i<font_height;i++,dest_offset+=stride)
    		{
    			dest_byte_offset = 0;
    			for(j=0;j<font_width*bit_per_pix;j++,cur_pix++)
    			{
    				u32_offset =  cur_pix & 0x1F;
    				if(u32_offset == 0)
    					u32	 = *(pu32 + (cur_pix>>5));
    				dest_bit_offset = j & 0x07;
                    #ifdef SUPPORT_MULTI_TASK
    				if(dest_bit_offset ==0)
    					font_byte = font_bitmap[tsk_id - 1] +(dest_offset + dest_byte_offset++);
                    #else
                    if(dest_bit_offset ==0)
    					font_byte = &font_bitmap[dest_offset + dest_byte_offset++];
                    #endif
    				if(u32 & (0x80000000>>u32_offset) )
    					*font_byte |= (0x80>> dest_bit_offset);
    			}
    		}
        }
        #ifdef SUPPORT_MULTI_TASK
        pbDatabuf = font_bitmap[tsk_id - 1];
        #else
		pbDatabuf = font_bitmap;
        #endif
#ifdef SCALE_FONT_SUPPORT
        #ifdef SUPPORT_MULTI_TASK
		UINT8 *scale_data_buffer = font_bitmap[tsk_id - 1]+FONT_BMP_LEN/2;
        if(OSD_ScaleCharMatrix(wLibClass, font_width, font_height, font, pObjectInfo, font_bitmap[tsk_id - 1], scale_data_buffer, bit_per_pix))
		{
			pbDatabuf = scale_data_buffer;
		}
        #else
        UINT8 *scale_data_buffer = font_bitmap+FONT_BMP_LEN/2;
        if(OSD_ScaleCharMatrix(wLibClass, font_width, font_height, font, pObjectInfo, font_bitmap, scale_data_buffer, bit_per_pix))
		{
			pbDatabuf = scale_data_buffer;
		}
        #endif
		
#endif
#ifdef GE_DRAW_OSD_LIB
        pbDatabuf = (UINT8 *)pu32;
#endif
		RSC_PRINTF("Get LIB_ICON:  0x%04x,wIndex=%d OK!\n",wLibClass,wIndex);
		
	}
	else if(wClass==LIB_PALLETE)
	{
		RSC_PRINTF("Get LIB_PALLETE: 0x%04x,wIndex=%d\n",wLibClass,wIndex);
        wIndex &= 0x0F;
        if(wIndex>=sizeof(palette_array)/sizeof(palette_array[0]))
            wIndex = 0;
        pbDatabuf = palette_array[wIndex];
	}
	else
	{
		RSC_PRINTF("Get Unkown data: 0x%04x,wIndex=%d\n",wLibClass,wIndex);
		return NULL;
	}

	return pbDatabuf;

}

UINT8 *OSD_GetThaiCellData_ext(UINT16 wLibClass, struct thai_cell *cell, OBJECTINFO *pObjectInfo, UINT8 *font_bitmap_ext)
{
	const font_t *font_subt[3];
	UINT16 wIndex[3],stride;
	UINT8* pbDatabuf,*font_byte=NULL;
	UINT32 i,j,k,font_width,font_height,font_max_width;
	UINT32 *pu32;
	UINT32 size,data_offset,u32 = 0,u32_offset,bit_offset,cur_pix;
	UINT32 dest_pix, dest_offset,dest_byte_offset,dest_bit_offset;
	UINT32 *font_word = NULL, *font_buf;
	
	pObjectInfo->m_wObjClass = wLibClass;

	font_max_width = 0;
	font_height = 0;

	if(wLibClass &0xF000 != LIB_FONT)
		return NULL;
	
	for(i=0; i<cell->char_num; i++)
	{
		wIndex[i] = cell->unicode[i];
		font_subt[i] = get_font(wLibClass,&wIndex[i]);
		if(font_subt[i]==NULL)	
			return NULL;

		if(font_max_width < font_subt[i]->width[wIndex[i]])
		{
			font_max_width = font_subt[i]->width[wIndex[i]];
			font_height =  font_subt[i]->height;
		}
	}

	pObjectInfo->m_objAttr.m_wWidth = (font_max_width+7)/8*8;
	pObjectInfo->m_objAttr.m_wHeight = font_height;
	pObjectInfo->m_objAttr.m_wActualWidth = font_max_width;
	pObjectInfo->m_objAttr.m_bColor	= 1;
	stride = (font_max_width+7)/8;
	MEMSET(font_bitmap_ext, 0, font_height *pObjectInfo->m_objAttr.m_wWidth / 8);
	font_buf = MALLOC(((font_height*font_max_width+31)/32)*4);
	MEMSET(font_buf, 0, ((font_height*font_max_width+31)/32)*4);

	for(i=0; i<cell->char_num; i++)
	{
		// get wIndex font offset 
		data_offset = 0;
		for(j=0;j<wIndex[i];j++)
		{
			font_width = font_subt[i]->width[j];
			size = (font_width * font_height + 31)>>5;//32;
			data_offset += size;
		}
		//if(font_subt[i]->data_type == 0)
		//	pu32 = ((UINT8 *)font_subt[i]->data) + data_offset;
		//else if(font_subt[i]->data_type == 1)
		//	pu32 = ((UINT16 *)font_subt[i]->data) + data_offset;
		//else if(font_subt[i]->data_type == 2)
			pu32 = ((UINT32 *)font_subt[i]->data) + data_offset;
		//pu32 = (UINT32*)(font_subt[i]->data + data_offset);
		font_width = font_subt[i]->width[wIndex[i]];
		u32 = 0;
		cur_pix = 0;
		for(j=0; j<font_height; j++)
		{
			dest_byte_offset = 0;
			for(k=0; k<font_width; k++,cur_pix++)
			{
				u32_offset =  cur_pix & 0x1F;
				if(u32_offset == 0)
				{
					u32	 = *(pu32 + (cur_pix>>5)); 
				}

				dest_pix = j*font_max_width+font_max_width-font_width+k;
				dest_bit_offset = dest_pix & 0x1F;
				if(dest_bit_offset ==0||k==0)
				{
					font_word = (UINT32*)&font_buf[dest_pix>>5];
				}

				if(u32 & (0x80000000>>u32_offset) )
				{
					*font_word |= (0x80000000>> dest_bit_offset);
				}
			}
		} 
	}

	pu32 = font_buf;
	font_width = font_max_width;
	cur_pix = 0;
	dest_offset = 0;
	u32 = 0; 
	//if(OSD_Get_Vscr_State())
	{
		for(i=0;i<font_height;i++,dest_offset+=stride)
		{
			dest_byte_offset = 0;
			for(j=0;j<font_width;j++,cur_pix++)
			{
				u32_offset =  cur_pix & 0x1F;
				if(u32_offset == 0)
					u32	 = *(pu32 + (cur_pix>>5));
				dest_bit_offset = j & 0x07;

				if(dest_bit_offset ==0)
	    				font_byte = &font_bitmap_ext[dest_offset + dest_byte_offset++];
	  
				if(u32 & (0x80000000>>u32_offset) )
				{
					*font_byte |= (0x80>> dest_bit_offset); 
				}
			}
		}
	} 

	FREE(font_buf);
	pbDatabuf = font_bitmap_ext;
	return pbDatabuf;
}

UINT8 *OSD_GetRscObjData_ext(UINT16 wLibClass, UINT16 uIndex, OBJECTINFO *pObjectInfo, UINT8 *font_bitmap_ext)
{
	UINT16 wIndex, wClass, stride;
	UINT16 wSite;

	const unsigned char *str_array;

	const font_t *font;
	bitmap_infor_t *bmpinfo;

	BOOL fStatus;
	UINT8 *pbDatabuf;


	unsigned long i, j, font_width, font_height;
	const unsigned long *pu32;
	unsigned long offset, size, data_offset, u32 = 0, u32_offset, bit_offset, cur_pix, dest_offset, dest_byte_offset, dest_bit_offset;
	unsigned char *font_byte = NULL;
	unsigned long str_num;

	RSC_PRINTF("Call %s:\n", __FUNCTION__);

	pObjectInfo->m_wObjClass = wLibClass;

	wIndex = uIndex; //ComMB16ToWord(pbIndex);
	wClass = wLibClass &0xF000;

	if (wClass == LIB_ICON)
	{
		wIndex -= 0x8001;

		RSC_PRINTF("Get LIB_ICON: 0x%04x,wIndex=%d\n", wLibClass, wIndex);

		if (wIndex >= sizeof(bitmaps_infor) / sizeof(bitmaps_infor[0]))
		{
			return NULL;
		}

		bmpinfo = &bitmaps_infor[wIndex];

		pObjectInfo->m_objAttr.m_wWidth = bmpinfo->bmp_size / bmpinfo->h;
		pObjectInfo->m_objAttr.m_wHeight = bmpinfo->h;
		pObjectInfo->m_objAttr.m_wActualWidth = bmpinfo->w;
		pObjectInfo->m_objAttr.m_bColor = 8;

	#ifdef BIDIRECTIONAL_OSD_STYLE
        check_mirror_flag(wLibClass,uIndex, pObjectInfo);
#endif
		//		pbDatabuf = MALLOC(bmpinfo->bmp_size);
		if (bmpinfo->bmp_size > sizeof(font_bitmap_ext))
		{
			return NULL;
		}
		else
			pbDatabuf = font_bitmap_ext;
		if (pbDatabuf != NULL)
		{
			if (bmp_rle_decode(bmpinfo->data, bmpinfo->data_size, pbDatabuf) != bmpinfo->bmp_size)
			{
				//FREE(pbDatabuf);
				pbDatabuf = NULL;
			}
			//else    printf("MALLOC 0X%08X(%dK)id=%d\t",pbDatabuf,bmpinfo->bmp_size/1024,wIndex);
		}

		//	pbDatabuf = bmpinfo->data;

	}
	else if (wClass == LIB_STRING)
	{
		wIndex -= 1;
		str_array = cur_string;
		RSC_PRINTF("0x%02x,0x%02x,0x%02x \n", str_array[0], str_array[1], str_array[2]);

		str_num = (str_array[1] << 8) + str_array[2];

		RSC_PRINTF("Get LIB_STRING: 0x%04x,wIndex=%d,str_num=%d\n", wLibClass, wIndex, str_num);
		if (wIndex >= str_num)
		{
			return NULL;
		}

		offset = (str_array[3+2 * wIndex] << 8) + str_array[3+2 * wIndex + 1];

		pbDatabuf = (UINT8*) &str_array[offset];
		RSC_PRINTF("Get LIB_STRING: 0x%04x,wIndex=%d,offset=%d,pbDatabuf=0x%x\n", wLibClass, wIndex, offset, pbDatabuf);

	}
	else if (wClass == LIB_FONT)
	{


		RSC_PRINTF("Get LIB_ICON:  0x%04x,wIndex=%d\n", wLibClass, wIndex);

		font = get_font_1bit(wLibClass, &wIndex);
		if (font == NULL)
		{
			return NULL;
		}

		pObjectInfo->m_objAttr.m_wWidth = (font->width[wIndex] + 7) / 8 * 8;
		font_height = pObjectInfo->m_objAttr.m_wHeight = font->height;
		pObjectInfo->m_objAttr.m_wActualWidth = font->width[wIndex];
		pObjectInfo->m_objAttr.m_bColor = 1;
		MEMSET(font_bitmap_ext, 0, font_height *pObjectInfo->m_objAttr.m_wWidth / 8);
		data_offset = 0;
		for (i = 0; i < wIndex; i++)
		{
			font_width = font->width[i];
			size = (font_width *font_height + 31) >> 5; //32;
			data_offset += size;
		}

		pu32 = font->data + data_offset;
		font_width = font->width[wIndex];
		stride = (font_width + 7) / 8;
		cur_pix = 0;
		dest_offset = 0;
		RSC_PRINTF("%c,font_width=%d,font_height=%d,stride=%d,data_offset=%d\n", wIndex, font_width, font_height, stride, data_offset);
		u32 = 0;
		for (i = 0; i < font_height; i++, dest_offset += stride)
		{
			dest_byte_offset = 0;
			for (j = 0; j < font_width; j++, cur_pix++)
			{
				u32_offset = cur_pix &0x1F;
				if (u32_offset == 0)
					u32 = *(pu32 + (cur_pix >> 5));
				dest_bit_offset = j &0x07;
				if (dest_bit_offset == 0)
					font_byte = &font_bitmap_ext[dest_offset + dest_byte_offset++];
				if (u32 &(0x80000000 >> u32_offset))
					*font_byte |= (0x80 >> dest_bit_offset);
			}
		}

		pbDatabuf = font_bitmap_ext;
		RSC_PRINTF("Get LIB_ICON:  0x%04x,wIndex=%d OK!\n", wLibClass, wIndex);

	}
	else if (wClass == LIB_PALLETE)
	{
		RSC_PRINTF("Get LIB_PALLETE: 0x%04x,wIndex=%d\n", wLibClass, wIndex);
		wIndex &= 0x0F;
		if (wIndex >= sizeof(palette_array) / sizeof(palette_array[0]))
			wIndex = 0;
		pbDatabuf = palette_array[wIndex];
	}
	else
	{
		RSC_PRINTF("Get Unkown data: 0x%04x,wIndex=%d\n", wLibClass, wIndex);
		return NULL;
	}

	return pbDatabuf;

}


BOOL OSD_GetObjInfo(UINT16 wLibClass,UINT16 uIndex/*UINT8* pbIndex*/,OBJECTINFO* pObjectInfo)
{
	UINT16	wClass,wIndex,i;
	UINT32	dwOffset;
	const font_t*	font;
	bitmap_infor_t* bmpinfo;

	
	RSC_PRINTF("Call %s:\n",__FUNCTION__);

	pObjectInfo->m_wObjClass = wLibClass;

	
	// the content dwIndex points to is UNICODE. 
    wIndex= uIndex;//ComLB16ToWord(pbIndex);

	// ADD operation help to Get the high-level resource-type
	// add 0x80 to in case of so many string type
	wClass=wLibClass&0xF000;

	// check for security
	// if the lib is one of the following two,pObjectInfo maynot be a empty value
	if(((wClass==LIB_FONT)||(wClass==LIB_ICON))&&(pObjectInfo==NULL))
		return 0;
	if(wClass==LIB_FONT)
	{

		font = get_font(wLibClass,&wIndex);
		if(font==NULL)	return FALSE;

#ifdef SCALE_FONT_SUPPORT
		UINT32 fontsize = get_font_size_index(wLibClass);
		UINT32 font_width = font->width[wIndex];
		font_width = font_width*font_size_ary[fontsize].w_mul/font_size_ary[fontsize].w_div;
		pObjectInfo->m_objAttr.m_wWidth 	= (font_width + 7)/8;
		pObjectInfo->m_objAttr.m_wHeight	= font->height*font_size_ary[fontsize].h_mul/font_size_ary[fontsize].h_div;
		pObjectInfo->m_objAttr.m_wActualWidth = font->width[wIndex]*font_size_ary[fontsize].w_mul/font_size_ary[fontsize].w_div;
#else
		pObjectInfo->m_objAttr.m_wWidth 	= (font->width[wIndex]+7)/8;
		pObjectInfo->m_objAttr.m_wHeight	= font->height;
		pObjectInfo->m_objAttr.m_wActualWidth = font->width[wIndex];
#endif		
		pObjectInfo->m_objAttr.m_bColor	= 1;
	}
	else if(wClass==LIB_ICON)
	{
	
		//PRINTF("Get LIB_ICON INFOR: 0x%04x,wIndex=%d\n",wLibClass,wIndex);
		wIndex -= 0x8001;
		
		if(wIndex>=sizeof(bitmaps_infor)/sizeof(bitmaps_infor[0]))
			return FALSE;

		bmpinfo = &bitmaps_infor[wIndex];
		pObjectInfo->m_objAttr.m_wWidth 	= bmpinfo->bmp_size/bmpinfo->h;
		pObjectInfo->m_objAttr.m_wHeight 	= bmpinfo->h;		
		pObjectInfo->m_objAttr.m_wActualWidth = bmpinfo->w;
		//pObjectInfo->m_objAttr.m_bColor	= 8;
		//pObjectInfo->m_objAttr.m_bColor = (bmpinfo->bmp_size/(bmpinfo->h*bmpinfo->w))<<3;
		pObjectInfo->m_objAttr.m_bColor = bmpinfo->bit_count;

	#ifdef BIDIRECTIONAL_OSD_STYLE
        check_mirror_flag(wLibClass,uIndex, pObjectInfo);
	#endif
	}
	else
	{
		
		RSC_PRINTF("Get Unkown infor: 0x%04x,wIndex=%d\n",wLibClass,wIndex);
		return FALSE;
	}

	
	RSC_PRINTF("Get INFOR: 0x%04x,wIndex=%d\n",wLibClass,wIndex);


	return TRUE;
}

BOOL   	OSD_ReleaseObjData(UINT8* lpDataBuf,lpOBJECTINFO pObjectInfo)
{
	if( (pObjectInfo->m_wObjClass&0xF000)==LIB_ICON && lpDataBuf!=NULL)
	{
	//	PRINTF("Free Bitmap!\n");
	    //printf("FREE 0X%08X\n",lpDataBuf);
		//FREE(lpDataBuf);
	}
//	else		PRINTF("Rleasee ObjData !!!!(0x%04x,0x%x)\n",pObjectInfo->m_wObjClass,lpDataBuf);
		
	return TRUE;
}

/**************************************************************************************
* Function Name:	OSD_GetDefaultFontLib 
*
* Description:		Get a character's FONT Library ID.
*					
* Arguments:
*		pString: 	IN;		The character pointer.
*
* Return value:		
*		ID_RSC:		The font Library ID of the caracter
*
* NOTES:	Its detecting order is: ASCII char, MASS char, the language we currently used.
*
**************************************************************************************/
ID_RSC OSD_GetDefaultFontLib(UINT16 uChar)
{    
    UINT8 hbyte,lbyte;

    hbyte = (UINT8)(uChar>>8);
    lbyte = (UINT8)uChar;
        
    if(uChar < 0x80)
        return LIB_FONT_DEFAULT;
#if(AOV_VIE_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0x00C0) && (uChar <= 0x01B0))
        return LIB_FONT_VIE;
#endif		
#if(AOV_ARABIC_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0x0600) && (uChar <= 0x06FF))
        return LIB_FONT_ARABIC;
#endif
#if(AOV_TAMIL_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0x0A00) && (uChar <= 0x0BFA))
        return LIB_FONT_TAM;
#endif		
#if(AOV_THAI_SUPPORT_ENABLE == SYS_FUNC_ON)
    else if((uChar >= 0x0E00) && (uChar <= 0x0E7F))
        return LIB_FONT_THAI;
#endif
#if(AOV_VIE_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0x1EA0) && (uChar <= 0x1EF9))
        return LIB_FONT_VIE;
#endif
#if(AOV_CHS_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0x4E00) && (uChar <= 0x9FA0))
        return LIB_FONT_CHS;
#endif
#if(AOV_ARABIC_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0xFB50) && (uChar <= 0xFEFC))
        return LIB_FONT_ARABIC;
#endif
#if(AOV_RUS_SUPPORT_ENABLE == SYS_FUNC_ON)||(AOV_UKRA_SUPPORT_ENABLE == SYS_FUNC_ON)
	else if((uChar >= 0x0401) && (uChar <= 0x0491))
        return LIB_FONT_CYRILLIC;
#endif


    else
        return OSDExt_GetFontLibId(OSD_GetLangEnvironment());

}


ID_RSC OSDExt_GetMsgLibId(UINT16 EnvID)
{
	lpLANG_TABLE	pLangTab = (lpLANG_TABLE)g_LangRscMapTable;
	UINT8			i;

	for (i=0; i<SIZE_LANG_TABLE; i++)
	{
		if (pLangTab->LangId == EnvID)
			return pLangTab->StrId;
		else
			pLangTab++;
	}
	return LIB_STRING_ENGLISH;
}

PWINSTYLE OSDExt_GetWinStyle(UINT8 bIdx)
{
	if (bIdx < SIZE_WINSTYLE)
		return winstyle_array[cur_wstyle] + bIdx;
	else
		return winstyle_array[cur_wstyle] +0;	// Error Handle
}

#if defined(SUPPORT_VMX_STD) || defined(SUPPORT_VMX)
void OSDExt_SetWinStyle(UINT8 bIdx, UINT32 bColor, UINT32 fColor)
{
	PWINSTYLE t_winstyle;
	t_winstyle = winstyle_array[cur_wstyle] + bIdx;
	if( bIdx != WSTL_OSM_POP_UP_TEXT_FG_BLACK)
		t_winstyle->wBgIdx = bColor;
	t_winstyle->wFgIdx = fColor;
	
//	memcpy(winstyle_array[cur_wstyle] + bIdx, winstyle, sizeof(WINSTYLE));
}
#endif

#ifdef BIDIRECTIONAL_OSD_STYLE
BOOL OSD_GetMirrorFlag(void)
{
	return mirror_flag;
}
#endif

